import Ball from "./Ball";
import Barrier from "./Barrier";
import Config from "./Config";

const { ccclass, property } = cc._decorator;

@ccclass
export default class MainController extends cc.Component {

    @property(cc.Prefab)
    prefabBall: cc.Prefab = null;
    @property([cc.Prefab])
    prefabBarries: cc.Prefab[] = [];
    @property([Ball])
    balls: Ball[] = [];
    barriers: Barrier[] = [];
    recycleBallsCount: number = 1;

    // LIFE-CYCLE CALLBACKS:
    onLoad() {
        this.addBarriers();
        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.balls[0].main = this;
        this.balls[0].node.group = Config.groupBallInRecycle;
        this.balls[0].getComponent(cc.PhysicsCircleCollider).apply();
    }

    start() {

    }

    // update (dt) {}

    onTouchStart(evt: cc.Event.EventTouch) {
        if (!this.isRecycleFinish()) {
            return;
        }
        this.recycleBallsCount = 0;
        let touchPos = this.node.convertToNodeSpaceAR(evt.touch.getLocation());
        this.shootBalls(touchPos.sub(cc.v2(0, 243)))
    }

    addBall(pos: cc.Vec2) {
        let ball = cc.instantiate(this.prefabBall).getComponent(Ball);
        ball.node.parent = this.node;
        ball.node.position = pos;
        ball.main = this;
        ball.node.group = Config.groupBallInGame;
        ball.getComponent(cc.PhysicsCircleCollider).apply();
        this.balls.push(ball);
        // console.log('addBall')
    }

    shootBalls(dir: cc.Vec2) {
        for (let i = 0; i < this.balls.length; ++i) {
            let ball = this.balls[i];
            this.scheduleOnce(() => {
                this.shootBall(ball, dir);
            }, i * 0.3);
        }
    }

    shootBall(ball: Ball, dir: cc.Vec2) {
        ball.rigidBody.active = false;
        let poses: cc.Vec2[] = [];
        poses.push(ball.node.position);
        poses.push(cc.v2(0, 490));
        poses.push(cc.v2(0, 420));
        ball.node.group = Config.groupBallInGame;
        ball.getComponent(cc.PhysicsCircleCollider).apply();
        // console.log(ball.node.group);

        ball.node.runAction(cc.sequence(
            cc.cardinalSplineTo(0.8, poses, 0.5),
            cc.callFunc(() => {
                ball.rigidBody.active = true;
                ball.rigidBody.linearVelocity = dir.mul(3);
            })
        ));

    }

    recycleBall() {
        this.recycleBallsCount++;
        if (this.isRecycleFinish()) {
            for (let i = 0; i < this.barriers.length; ++i) {
                let barrier = this.barriers[i];
                barrier.node.runAction(cc.moveBy(0.5, cc.v2(0, 120)));
            }
            this.addBarriers();
        }
    }

    isRecycleFinish(): boolean {
        return this.recycleBallsCount === this.balls.length;
    }

    addBarriers() {
        let startPosX = -310;
        let endPosX = 230;
        let currentPosX = startPosX + this.getRandomSpace();
        while (currentPosX < endPosX) {
            let barrier = cc.instantiate(this.prefabBarries[Math.floor(Math.random() * this.prefabBarries.length)]).getComponent(Barrier) as Barrier;
            // this.node.addChild(barrier.node);
            barrier.node.parent = this.node;
            barrier.node.rotation = Math.random() * 360;
            barrier.node.position = cc.v2(currentPosX, -410);
            barrier.main = this;
            currentPosX += this.getRandomSpace();
            this.barriers.push(barrier);
        }
    }

    getRandomSpace(): number {
        return 100 + Math.random() * 100;
    }

    removeBarrier(barrier: Barrier) {
        let idx = this.barriers.indexOf(barrier);
        if (idx != -1) {
            barrier.node.removeFromParent(false)
            this.barriers.splice(idx, 1);
        }
    }


}
